package main

import (
	"fmt"
	"ginstu/routers"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
)

func initMiddle(c *gin.Context) {
	fmt.Println("start initMiddle")

	c.Next()

	fmt.Println("end initMiddle")
}
func secondMiddle(c *gin.Context) {
	fmt.Println("start secondMiddle")
	c.Next()
	fmt.Println("end secondMiddle")
}
func shareMiddle(c *gin.Context) {
	c.Set("username", "tiger")
}
func main() {
	// gin.Default 默认携带 logger recovery中间件， 如不想使用 可改 gin.New()
	r := gin.Default()
	// 配置 session 全局中间件  传参为加密密钥 ==> 必须保证定义在入口的 gin.default 下
	store := cookie.NewStore([]byte("secret"))
	// store 是存储引擎
	r.Use(sessions.Sessions("mysession", store))
	routers.AdminRoutersInit(r)
	routers.ApiRoutersInit(r)
	routers.DefaultRoutersInit(r)
	routers.CacheRoutersInit(r)

	// 中间件 1  next == > next 方法后的内容在 gin 方法执行后继续执行
	r.GET("/middle1", initMiddle, func(c *gin.Context) {
		c.JSON(200, gin.H{"message": "middle1"})
		fmt.Println("router middle1") // 执行流程 start -> router ->  end
	})

	// 中间件 2  Abort ==> 不常用 不在编写

	// 中间件 3  多next执行流程
	r.GET("/middle2", initMiddle, secondMiddle, func(c *gin.Context) {
		c.JSON(200, gin.H{"message": "middle2"})
		fmt.Println(" middle2")
		// start initMiddle -> start secondMiddle -> middle2 -> end secondMiddle -> end initMiddle
	})

	// 中间件 4 全局中间件 r.Use(func1, func2 , func3...) 定义全局中间件， 所有路由都会先执行
	// 不在赘述

	// 中间件 5 路由分组中间件
	middleRouter := r.Group("/middleRouter")
	middleRouter.Use(initMiddle)
	{
		middleRouter.GET("m1", func(ctx *gin.Context) {
			ctx.JSON(200, gin.H{"message": "m1"})
			fmt.Println("m1")
			// 执行流程
			// start initMiddle -> m1 -> end initMiddle
		})
	}

	// 中间件与 controller 之间数据共享
	r.GET("/share", shareMiddle, func(c *gin.Context) {
		username, _ := c.Get("username")
		c.JSON(200, gin.H{"message": username})
	})

	// 中间件使用 goroutine == > 需要将c 使用c.copy复制出来才可在routine里使用
	/*
		r.GET("/",func(c *gin.Context) {
			ccp := c.Copy()
			go func() {
			// simulate a long task with '
			// 这里使用你创建的副本
				fmt.Println("Done! in path " + cCp.Request.URL.Path)
			}()
			c.String(200,"首页")
	*/
	err := r.Run()
	if err != nil {
		return
	}
}
